#pragma once

// log
#define LOG_EN
#ifdef LOG_EN
#include <stdio.h>
#include <stdarg.h>
#include <time.h>

// define your log level
#define LOG_LEVEL (LOG_LEVEL_DEBUG | LOG_LEVEL_INFO | LOG_LEVEL_WARN | LOG_LEVEL_ERROR)

#define LOG_LEVEL_NONE  0
#define LOG_LEVEL_DEBUG 0x1
#define LOG_LEVEL_INFO  0x2
#define LOG_LEVEL_WARN  0x4
#define LOG_LEVEL_ERROR 0x8
#define LOG_LEVEL_ALL 0xffffffff

#define LOG(type, fmt, args...)  \
  do{\
    time_t t = time(NULL);\
    struct tm *l = localtime(&t);\
    printf("[%s][%04d-%02d-%02d %02d:%02d:%02d][%s, line: %d] ", type, l->tm_year+1900, l->tm_mon+1, l->tm_mday, l->tm_hour, l->tm_min, l->tm_sec, __FILE__, __LINE__);\
    printf(fmt, ##args);\
    printf("\n");\
  }while(0)
#if LOG_LEVEL&LOG_LEVEL_DEBUG
#define LOG_DEBUG(fmt, args...) LOG("DEBUG", fmt, ##args)
#else 
#define LOG_DEBUG(fmt, args...)
#endif  /* LOG_LEVEL_DEBUG */
#if LOG_LEVEL&LOG_LEVEL_INFO
#define LOG_INFO(fmt, args...) LOG("INFO", fmt, ##args)
#else 
#define LOG_INFO(fmt, args...)
#endif  /* LOG_LEVEL_INFO */
#if LOG_LEVEL&LOG_LEVEL_WARN
#define LOG_WARN(fmt, args...) LOG("WARNING", fmt, ##args)
#else 
#define LOG_WARN(fmt, args...)
#endif  /* LOG_LEVEL_WARN */
#if LOG_LEVEL&LOG_LEVEL_ERROR
#define LOG_ERROR(fmt, args...) LOG("ERROR", fmt, ##args)
#else 
#define LOG_ERROR(fmt, args...)
#endif  /* LOG_LEVEL_ERROR */
#define LOG_ASSERT(fmt, args...) do{LOG("assert", fmt, ##args);exit(-1);}while(0)
#define LOG_HEX(data, len, line_num) {printf("===HEX at %s===", #data); for(int i=0; i<len; i++) {if(i%line_num==0) printf("\n"); printf("%02x ", data[i]&0xff);} printf("\n====end====\n");}
#else
#define LOG(fmt, args...)  
#define LOG_DEBUG(fmt, args...)
#define LOG_INFO(fmt, args...)
#define LOG_WARN(fmt, args...)
#define LOG_ERROR(fmt, args...)
#define LOG_ASSERT(fmt, args...) {sprintf(stderr, "assert at [%s %d]!!! \n", __FILE__, __LINE__);}
#define LOG_HEX(data, len, line_num)
#endif  /* LOG_EN */

// operating system
#if defined(_WIN32) || defined(_WIN64)   // windows system
#define OPERATING_SYSTEM "Windows"
#elif defined(__APPLE__)  // ios system
#define OPERATING_SYSTEM "IOS"
#elif defined(__linux__)  // linux system
#define OPERATING_SYSTEM "Linux"
#else   // unknow
#define OPERATING_SYSTEM "Unknow system"
#endif

// architecture
#ifdef __x86_64__
#define COMPLATE_ARCHITECTURE "Compiled for 64-bit x86-64 (AMD64/Intel 64) architecture"
#elif defined(__i386__) || defined(__i386)  // 添加__i386以兼容不同的编译器
#define COMPLATE_ARCHITECTURE "Compiled for 32-bit x86 (IA-32) architecture"
#elif defined(__aarch64__)
#define COMPLATE_ARCHITECTURE "Compiled for 64-bit ARM64 (aarch64) architecture"  
#elif defined(__arm__) && !defined(__aarch64__)
#define COMPLATE_ARCHITECTURE "Compiled for 32-bit ARM (armvX) architecture"
    // 注意：armvX是一个通用术语，可能需要根据实际ARM版本进一步指定
#elif defined(__riscv) || defined(__riscv__)
#define COMPLATE_ARCHITECTURE "Compiled for RISC-V architecture"
#elif defined(__mips64) || defined(__mips64__)
#define COMPLATE_ARCHITECTURE "Compiled for 64-bit MIPS architecture"  
#elif defined(__mips__)
#define COMPLATE_ARCHITECTURE "Compiled for 32-bit MIPS architecture"
#else
#define COMPLATE_ARCHITECTURE "Unknown architecture"
#endif

//  c compiler
#if defined(__clang__)   // clang
#define C_COMPILER "Clang Compiler"
#elif defined(__GNUC__)     // gcc/g++ 
#define C_COMPILER "GNU C/C++ Compiler"
#elif defined(_MSC_VER)     // vc
#define C_COMPILER "MSVC Compiler"
#define GLOBLE_COUNTER __counter__  // each using __counter__ , __counter__ will add 1
#else
#define C_COMPILER "Unknown Compiler"
#endif

// debug or complite macro 
#define SRC_FILE __FILE__   // version.h
#define SRC_LINE __LINE__   // 61
#define SRC_FUNCTION __FUNCTION__   // print function name. (c++ use __func__ )
#define COMPLILE_TIME __TIME__  // "09:12:55"
#define COMPLILE_DATE __DATE__  // "Jul 10 2024"

// deprecated
#ifdef __GNUC__     // GCC
#define DEPRECATED(fun, message)  fun __attribute__ ((deprecated(message)))
#elif defined(_MSC_VER)     // MSVC
#define DEPRECATED(fun, message)  __declspec(deprecated(message)) fun
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(fun, message)
#endif

// gcc version
#define GCC_VERSION __STDC_VERSION__	// c11 -> 201112
